Display the XIM status callbacks with a popup window. (Patch from
authorOwen Taylor <otaylor@redhat.com>
Fri, 7 Dec 2001 23:15:32 +0000 (23:15 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Fri, 7 Dec 2001 23:15:32 +0000 (23:15 +0000)
Fri Dec  7 16:05:22 2001  Owen Taylor  <otaylor@redhat.com>

        * modules/input/gtkimcontextxim.c: Display the XIM
        status callbacks with a popup window. (Patch from
        HideToshi Tajima, #50628, somewhat modified.)

ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
modules/input/gtkimcontextxim.c
modules/input/gtkimcontextxim.h

index 4258c34b99c41eb9ff1474b4275d022a91877e0d..09bab640cb02d30ce69645e85c5d79bb93a525c8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Fri Dec  7 16:05:22 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * modules/input/gtkimcontextxim.c: Display the XIM
+       status callbacks with a popup window. (Patch from
+       HideToshi Tajima, #50628, somewhat modified.)
+
 Fri Dec  7 12:07:15 2001  Tim Janik  <timj@gtk.org>
 
        * gtk/Makefile.am: each source generation rule needs to use its own
index 4258c34b99c41eb9ff1474b4275d022a91877e0d..09bab640cb02d30ce69645e85c5d79bb93a525c8 100644 (file)
@@ -1,3 +1,9 @@
+Fri Dec  7 16:05:22 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * modules/input/gtkimcontextxim.c: Display the XIM
+       status callbacks with a popup window. (Patch from
+       HideToshi Tajima, #50628, somewhat modified.)
+
 Fri Dec  7 12:07:15 2001  Tim Janik  <timj@gtk.org>
 
        * gtk/Makefile.am: each source generation rule needs to use its own
index 4258c34b99c41eb9ff1474b4275d022a91877e0d..09bab640cb02d30ce69645e85c5d79bb93a525c8 100644 (file)
@@ -1,3 +1,9 @@
+Fri Dec  7 16:05:22 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * modules/input/gtkimcontextxim.c: Display the XIM
+       status callbacks with a popup window. (Patch from
+       HideToshi Tajima, #50628, somewhat modified.)
+
 Fri Dec  7 12:07:15 2001  Tim Janik  <timj@gtk.org>
 
        * gtk/Makefile.am: each source generation rule needs to use its own
index 4258c34b99c41eb9ff1474b4275d022a91877e0d..09bab640cb02d30ce69645e85c5d79bb93a525c8 100644 (file)
@@ -1,3 +1,9 @@
+Fri Dec  7 16:05:22 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * modules/input/gtkimcontextxim.c: Display the XIM
+       status callbacks with a popup window. (Patch from
+       HideToshi Tajima, #50628, somewhat modified.)
+
 Fri Dec  7 12:07:15 2001  Tim Janik  <timj@gtk.org>
 
        * gtk/Makefile.am: each source generation rule needs to use its own
index 4258c34b99c41eb9ff1474b4275d022a91877e0d..09bab640cb02d30ce69645e85c5d79bb93a525c8 100644 (file)
@@ -1,3 +1,9 @@
+Fri Dec  7 16:05:22 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * modules/input/gtkimcontextxim.c: Display the XIM
+       status callbacks with a popup window. (Patch from
+       HideToshi Tajima, #50628, somewhat modified.)
+
 Fri Dec  7 12:07:15 2001  Tim Janik  <timj@gtk.org>
 
        * gtk/Makefile.am: each source generation rule needs to use its own
index 4258c34b99c41eb9ff1474b4275d022a91877e0d..09bab640cb02d30ce69645e85c5d79bb93a525c8 100644 (file)
@@ -1,3 +1,9 @@
+Fri Dec  7 16:05:22 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * modules/input/gtkimcontextxim.c: Display the XIM
+       status callbacks with a popup window. (Patch from
+       HideToshi Tajima, #50628, somewhat modified.)
+
 Fri Dec  7 12:07:15 2001  Tim Janik  <timj@gtk.org>
 
        * gtk/Makefile.am: each source generation rule needs to use its own
index 4258c34b99c41eb9ff1474b4275d022a91877e0d..09bab640cb02d30ce69645e85c5d79bb93a525c8 100644 (file)
@@ -1,3 +1,9 @@
+Fri Dec  7 16:05:22 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * modules/input/gtkimcontextxim.c: Display the XIM
+       status callbacks with a popup window. (Patch from
+       HideToshi Tajima, #50628, somewhat modified.)
+
 Fri Dec  7 12:07:15 2001  Tim Janik  <timj@gtk.org>
 
        * gtk/Makefile.am: each source generation rule needs to use its own
index 2f5faeb3b1e99fb87a14517622532d27af9a88d5..9b0240148f0cdb84be034f42478390de322f65d8 100644 (file)
@@ -20,7 +20,9 @@
 #include "locale.h"
 #include <string.h>
 
+#include "gtk/gtklabel.h"
 #include "gtk/gtksignal.h"
+#include "gtk/gtkwindow.h"
 #include "gtkimcontextxim.h"
 
 struct _GtkXIMInfo
@@ -49,6 +51,11 @@ static void     gtk_im_context_xim_get_preedit_string (GtkIMContext          *co
                                                       PangoAttrList        **attrs,
                                                       gint                  *cursor_pos);
 
+static void status_window_show     (GtkIMContextXIM *context_xim);
+static void status_window_hide     (GtkIMContextXIM *context_xim);
+static void status_window_set_text (GtkIMContextXIM *context_xim,
+                                   const gchar     *text);
+
 static XIC       gtk_im_context_xim_get_ic            (GtkIMContextXIM *context_xim);
 static GObjectClass *parent_class;
 
@@ -397,6 +404,9 @@ gtk_im_context_xim_focus_in (GtkIMContext *context)
     return;
 
   XSetICFocus (ic);
+
+  status_window_show (context_xim);
+
   return;
 }
 
@@ -410,6 +420,9 @@ gtk_im_context_xim_focus_out (GtkIMContext *context)
     return;
 
   XUnsetICFocus (ic);
+
+  status_window_hide (context_xim);
+
   return;
 }
 
@@ -473,6 +486,9 @@ gtk_im_context_xim_reset (GtkIMContext *context)
     return;
   
 
+  if (context_xim->preedit_length == 0)
+    return;
+
   preedit_attr = XVaCreateNestedList(0,
                                      XNPreeditState, &preedit_state,
                                      0);
@@ -609,7 +625,6 @@ preedit_start_callback (XIC      xic,
   GtkIMContext *context = GTK_IM_CONTEXT (client_data);
   
   g_signal_emit_by_name (context, "preedit_start");
-  g_print ("Starting preedit!\n");
 }                   
 
 static void
@@ -620,7 +635,6 @@ preedit_done_callback (XIC      xic,
   GtkIMContext *context = GTK_IM_CONTEXT (client_data);
   
   g_signal_emit_by_name (context, "preedit_end");  
-  g_print ("Ending preedit!\n");
 }                   
 
 static gint
@@ -773,7 +787,7 @@ status_start_callback (XIC      xic,
                       XPointer client_data,
                       XPointer call_data)
 {
-  g_print ("Status start\n");
+  return;
 } 
 
 static void
@@ -781,7 +795,7 @@ status_done_callback (XIC      xic,
                      XPointer client_data,
                      XPointer call_data)
 {
-  g_print ("Status done!\n");
+  return;
 }
 
 static void
@@ -791,18 +805,19 @@ status_draw_callback (XIC      xic,
 {
   GtkIMContextXIM *context = GTK_IM_CONTEXT_XIM (client_data);
 
-  g_print ("Status draw\n");
   if (call_data->type == XIMTextType)
     {
       gchar *text;
       xim_text_to_utf8 (context, call_data->data.text, &text);
 
       if (text)
-       g_print ("  %s\n", text);
+       status_window_set_text (context, text);
+      else
+       status_window_set_text (context, "");
     }
   else                         /* bitmap */
     {
-      g_print ("   bitmap id = %#lx\n", call_data->data.bitmap);
+      g_print ("Status drawn with bitmap - id = %#lx\n", call_data->data.bitmap);
     }
 }
 
@@ -889,3 +904,175 @@ gtk_im_context_xim_get_ic (GtkIMContextXIM *context_xim)
 
   return context_xim->ic;
 }
+
+/**************************
+ *                        *
+ * Status Window handling *
+ *                        *
+ **************************/
+
+static gboolean
+status_window_expose_event (GtkWidget      *widget,
+                           GdkEventExpose *event)
+{
+  gdk_draw_rectangle (widget->window,
+                     widget->style->base_gc [GTK_STATE_NORMAL],
+                     TRUE,
+                     0, 0,
+                     widget->allocation.width, widget->allocation.height);
+  gdk_draw_rectangle (widget->window,
+                     widget->style->text_gc [GTK_STATE_NORMAL],
+                     FALSE,
+                     0, 0,
+                     widget->allocation.width - 1, widget->allocation.height - 1);
+
+  return FALSE;
+}
+
+static void
+status_window_style_set (GtkWidget *toplevel,
+                        GtkStyle  *previous_style,
+                        GtkWidget *label)
+{
+  gint i;
+  
+  for (i = 0; i < 5; i++)
+    gtk_widget_modify_fg (label, i, &toplevel->style->text[i]);
+}
+
+static void
+status_window_destroy (GtkWidget *toplevel,
+                      GtkWidget *status_window)
+{
+  gtk_widget_destroy (status_window);
+  g_object_set_data (G_OBJECT (toplevel), "gtk-im-xim-status-window", NULL);
+}
+
+static gboolean
+status_window_configure (GtkWidget         *toplevel,
+                        GdkEventConfigure *event,
+                        GtkWidget         *status_window)
+{
+  GdkRectangle rect;
+  GtkRequisition requisition;
+  gint y;
+
+  gdk_window_get_frame_extents (toplevel->window, &rect);
+  gtk_widget_size_request (status_window, &requisition);
+
+  if (rect.y + rect.height + requisition.height < gdk_screen_height ())
+    y = rect.y + rect.height;
+  else
+    y = gdk_screen_height () - requisition.height;
+  
+  gtk_window_move (GTK_WINDOW (status_window), rect.x, y);
+
+  return FALSE;
+}
+
+static GtkWidget *
+status_window_get (GtkIMContextXIM *context_xim,
+                  gboolean         create)
+{
+  GdkWindow *toplevel_gdk;
+  GtkWidget *toplevel;
+  GtkWidget *status_window;
+  GtkWidget *status_label;
+  
+  if (!context_xim->client_window)
+    return NULL;
+
+  toplevel_gdk = context_xim->client_window;
+  while (TRUE)
+    {
+      GdkWindow *parent = gdk_window_get_parent (toplevel_gdk);
+      if (parent == gdk_get_default_root_window ())
+       break;
+      else
+       toplevel_gdk = parent;
+    }
+
+  gdk_window_get_user_data (toplevel_gdk, (gpointer *)&toplevel);
+  if (!toplevel)
+    return NULL;
+
+  status_window = g_object_get_data (G_OBJECT (toplevel), "gtk-im-xim-status-window");
+  if (status_window || !create)
+    return status_window;
+
+  status_window = gtk_window_new (GTK_WINDOW_POPUP);
+
+  gtk_window_set_policy (GTK_WINDOW (status_window), FALSE, FALSE, FALSE);
+  gtk_widget_set_app_paintable (status_window, TRUE);
+
+  status_label = gtk_label_new ("");
+  gtk_misc_set_padding (GTK_MISC (status_label), 1, 1);
+  gtk_widget_show (status_label);
+  
+  gtk_container_add (GTK_CONTAINER (status_window), status_label);
+
+  g_signal_connect (toplevel, "destroy",
+                   G_CALLBACK (status_window_destroy), status_window);
+  g_signal_connect (toplevel, "configure_event",
+                   G_CALLBACK (status_window_configure), status_window);
+
+  status_window_configure (toplevel, NULL, status_window);
+  
+  g_signal_connect (status_window, "style_set",
+                   G_CALLBACK (status_window_style_set), status_label);
+  g_signal_connect (status_window, "expose_event",
+                   G_CALLBACK (status_window_expose_event), NULL);
+  
+  g_object_set_data (G_OBJECT (toplevel), "gtk-im-xim-status-window", status_window);
+
+  return status_window;
+}
+
+static gboolean
+status_window_has_text (GtkWidget *status_window)
+{
+  GtkWidget *label = GTK_BIN (status_window)->child;
+  const gchar *text = gtk_label_get_text (GTK_LABEL (label));
+
+  return text[0] != '\0';
+}
+
+static void
+status_window_show (GtkIMContextXIM *context_xim)
+{
+  GtkWidget *status_window = status_window_get (context_xim, TRUE);
+
+  context_xim->status_visible = TRUE;
+  
+  if (status_window && status_window_has_text (status_window))
+    gtk_widget_show (status_window);
+}
+
+static void
+status_window_hide (GtkIMContextXIM *context_xim)
+{
+  GtkWidget *status_window = status_window_get (context_xim, FALSE);
+
+  context_xim->status_visible = FALSE;
+  
+  if (status_window)
+    gtk_widget_hide (status_window);
+}
+
+static void
+status_window_set_text (GtkIMContextXIM *context_xim,
+                       const gchar     *text)
+{
+  GtkWidget *status_window = status_window_get (context_xim, TRUE);
+
+  if (status_window)
+    {
+      GtkWidget *label = GTK_BIN (status_window)->child;
+      gtk_label_set_text (GTK_LABEL (label), text);
+      
+      if (context_xim->status_visible && status_window_has_text (status_window))
+       gtk_widget_show (status_window);
+      else
+       gtk_widget_hide (status_window);
+    }
+}
index 96d1df5eed44dc4ba0a6a457f5bff8663d4fcfab..ddda56826a8279764d4ca66717d86465f8644044 100644 (file)
@@ -72,6 +72,7 @@ struct _GtkIMContextXIM
   XIC ic;
 
   guint use_preedit : 1;
+  guint status_visible : 1;
 };
 
 struct _GtkIMContextXIMClass